<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/**
 * CodeIgniter SMACL Class
 *
 * This is ACL library for Codeigniter
 *
 * @package         CodeIgniter
 * @subpackage      Libraries
 * @category        Libraries
 * @author          DVC
 */
class Smacl
{

    private $_module;
    private $_controller;
    private $_action;
    private $_role_name;

    /**
     * Constructor
     * initialization parameters
     *
     * @access    public
     */
    public function __construct()
    {
        $this->ci = & get_instance();

        $this->ci->load->library('session');

        $this->ci->load->config('smacl');

        $this->_role_name = $this->getUserRole();

        $this->_module = CI::$APP->router->fetch_module();

        $this->_controller = CI::$APP->router->fetch_class();

        $this->_action = CI::$APP->router->fetch_method();

        $this->checkACL();
    }

    /**
     * Check User Access
     *
     * @access    public
     * @return    boolean
     */
    public function checkUserAccess($userid)
    {

        if ($userid == $this->getUserId()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Check Role Access
     *
     * @access    public
     * @return    boolean
     */
    public function checkRoleAccess($roles)
    {
        if (is_array($roles) && in_array($this->_role_name, $roles)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Get User ID
     *
     * @access    public
     * @return    Int
     */
    public function getUserId()
    {

        $var_user_id = $this->ci->config->item('session_userid_var');

        return $this->ci->session->userdata($var_user_id);
    }

    /**
     * Get User Role
     *
     * @access    public
     * @return    String
     */
    public function getUserRole()
    {
        $var_role_name = $this->ci->config->item('session_rol_var');

        $role_name = $this->ci->session->userdata($var_role_name);

        //set role default
        if (empty($role_name)) {
            $role_name = $this->ci->config->item('default_role');
        }

        return $role_name;
    }

    /**
     * Redirect Error Page
     *
     * @access    public
     * @return    void
     */
    public function redirectErrorPage()
    {

        $error_uri = $this->ci->config->item('class_error_page', $this->_module);

        $url = $this->ci->uri->assoc_to_uri(array($error_uri[0] => $error_uri[1], $error_uri[2] => ''));

        redirect($url, 'refresh');
    }

    /**
     * Redirect Login Page
     *
     * @access    public
     * @return    void
     */
    public function redirectLoginPage()
    {

        $login_assoc = $this->ci->config->item('class_login_page', $this->_module);

        $url = $this->ci->uri->assoc_to_uri(array($login_assoc[0] => $login_assoc[1], $login_assoc[2] => ''));

        redirect($url, 'refresh');
    }

    /**
     * Check ACL
     *
     * @access    private
     * @return    void
     */
    private function checkACL()
    {
        if ($this->ci->config->item('skip_check_controller', $this->_module)) {
            if (in_array($this->_controller, $this->ci->config->item('skip_check_controller', $this->_module))) {
                return true;
            }
        }

        //if exits role in list roles skip check, dont' check
        if (in_array($this->_module, $this->ci->config->item('skip_check_module'))) {
            return true;
        }

        //if exits role in list roles skip check, dont' check
        if (in_array($this->_role_name, $this->ci->config->item('skip_check_role'))) {
            return true;
        }


        $login_assoc = $this->ci->config->item('class_login_page', $this->_module);

        //dont' check ACL if this action is login
        if (!empty($login_assoc)) {
            if ($this->_module == $login_assoc[0] && $this->_controller == $login_assoc[1]
                    && $this->_action == $login_assoc[2]) {
                return true;
            }
        }

        //if module is backend and user is guest, redirect to login page
        if ($this->ci->config->item('module_backend') == $this->_module && $this->getUserRole() == 'guest')
            $this->redirectLoginPage();


        $error_assoc = $this->ci->config->item('class_error_page', $this->_module);

        //dont' check ACL if this action is login
        if (!empty($error_assoc)) {
            if ($this->_module == $error_assoc[0] && $this->_controller == $error_assoc[1]
                    && $this->_action == $error_assoc[2]) {
                return true;
            }
        }

        //Get rule of this module

        $rule = $this->ci->session->userdata('role_rule');
        if (isset($rule[$this->_module][$this->_controller][$this->_action])) {
            return true;
        } else {
            $this->redirectErrorPage();
        }
    }

}
